import UIKit

// 主视图控制者
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, GameCallback {
    @IBOutlet private weak var mButtonShowMenu: UIButton!   // "显示菜单"按钮
    private var mGame: Game!                                // 游戏
    private var mMenu: UIMenu!                              // 菜单
    private var mMenuItemEasy: UIAction!                    // "简单"菜单项
    private var mMenuItemMedium: UIAction!                  // "中等"菜单项
    private var mMenuItemHard: UIAction!                    // "困难"菜单项
    private var mMenuItemHasBorder: UIAction!               // "有"菜单项
    private var mMenuItemNoBorder: UIAction!                // "无"菜单项
    
    /**
     * 创建菜单。
     * @return 菜单
     */
    private func createMenu() -> UIMenu {
        // "开始"菜单项
        var title = NSLocalizedString("IDS_START", tableName: "Main", comment: "")
        let menuItemStart = UIAction(title: title) {
            _ in
            self.onMenuItemStartClicked()
        }

        // "简单"菜单项
        title = NSLocalizedString("IDS_EASY", tableName: "Main", comment: "")
        mMenuItemEasy = UIAction(title: title, subtitle: nil, image: nil, identifier: nil, discoverabilityTitle: nil, attributes: [], state: .on) {
            clickedMenuItem in
            self.onMenuItemSetDifficultyClicked(clickedMenuItem)
        }
        
        // "中等"菜单项
        title = NSLocalizedString("IDS_MEDIUM", tableName: "Main", comment: "")
        mMenuItemMedium = UIAction(title: title) {
            clickedMenuItem in
            self.onMenuItemSetDifficultyClicked(clickedMenuItem)
        }
        
        // "困难"菜单项
        title = NSLocalizedString("IDS_HARD", tableName: "Main", comment: "")
        mMenuItemHard = UIAction(title: title) {
            clickedMenuItem in
            self.onMenuItemSetDifficultyClicked(clickedMenuItem)
        }
        
        // "难度"菜单
        title = NSLocalizedString("IDS_SET_DIFFICULTY", tableName: "Main", comment: "")
        let menuDifficulty = UIMenu(title: title, subtitle: nil, image: nil, identifier: nil, options: [], children: [mMenuItemHard, mMenuItemMedium, mMenuItemEasy])

        // "有"菜单项
        title = NSLocalizedString("IDS_HAS_BORDER", tableName: "Main", comment: "")
        mMenuItemHasBorder = UIAction(title: title, subtitle: nil, image: nil, identifier: nil, discoverabilityTitle: nil, attributes: [], state: .on) {
            clickedMenuItem in
            self.onMenuItemSetBorderClicked(clickedMenuItem)
        }
        
        // "无"菜单项
        title = NSLocalizedString("IDS_NO_BORDER", tableName: "Main", comment: "")
        mMenuItemNoBorder = UIAction(title: title) {
            clickedMenuItem in
            self.onMenuItemSetBorderClicked(clickedMenuItem)
        }
        
        // "图片边框"菜单
        title = NSLocalizedString("IDS_SET_BORDER", tableName: "Main", comment: "")
        let menuBorder = UIMenu(title: title, subtitle: nil, image: nil, identifier: nil, options: [], children: [mMenuItemNoBorder, mMenuItemHasBorder])
        
        // "换图片"菜单项
        title = NSLocalizedString("IDS_SET_PICTURE", tableName: "Main", comment: "")
        let menuItemSetPicture = UIAction(title: title) {
            _ in
            self.onMenuItemSetPictureClicked()
        }
        
        // 选中菜单项
        if mGame != nil {
            mMenuItemEasy.state = mGame.difficulty == .EASY ? .on: .off
            mMenuItemMedium.state = mGame.difficulty == .MEDIUM ? .on: .off
            mMenuItemHard.state = mGame.difficulty == .HARD ? .on: .off
            mMenuItemHasBorder.state = mGame.pictureHasBorder ? .on: .off
            mMenuItemNoBorder.state = mGame.pictureHasBorder ? .off: .on
        }
        
        return UIMenu(title: "", subtitle: nil, image: nil, identifier: nil, options: [], children: [menuItemSetPicture, menuBorder, menuDifficulty, menuItemStart])
    }

    /**
     * 图片选择器的回调方法。
     * @param picker    图片选择器
     * @param info      用户选择的图片的相关信息
     */
     internal func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        // 获取用户选择的图片
        guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
            fatalError(NSLocalizedString("IDS_NOT_SUPPORT_IMAGE", tableName: "Main", comment: ""))
        }

        // 切换到横屏
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        appDelegate.allowPortrait = false

        // 关闭图片选择器
        super.dismiss(animated: true)

        // 设置图片
        mGame.setPicture(image.cgImage!)
    }

    /**
     * 游戏结束事件的响应方法。
     */
    internal func onGameOver() {
        // 显示胜利提示信息
        let text = NSLocalizedString("IDS_WON", tableName: "Main", comment: "")
        Toast.makeText(view, text: text, duration: Toast.LENGTH_LONG).show()
    }
    
    /**
     * "图片边框"菜单项的单击响应方法。
     * @param clickedMenuItem   用户单击的菜单项
     */
    private func onMenuItemSetBorderClicked(_ clickedMenuItem: UIAction) {
        // 如果要设置的参数与当前游戏参数相同，则直接返回
        let hasBorder = (clickedMenuItem == mMenuItemHasBorder)
        if hasBorder == mGame.pictureHasBorder {
            return
        }
        
        // 设置边框
        mGame.pictureHasBorder = hasBorder
        
        // 重新创建菜单
        mButtonShowMenu.menu = self.createMenu()
    }

    /**
     * "难度"菜单项的单击响应方法。
     * @param clickedMenuItem  用户单击的菜单项
     */
    private func onMenuItemSetDifficultyClicked(_ clickedMenuItem: UIAction) {
        // 如果要设置的参数与当前游戏参数相同，则直接返回
        var newDiff = Game.Difficulty.EASY
        if clickedMenuItem == mMenuItemMedium {
            newDiff = .MEDIUM
        } else if clickedMenuItem == mMenuItemHard {
            newDiff = .HARD
        }
        if newDiff == mGame.difficulty {
            return
        }

        // 弹出提示对话框
        let titleYes = NSLocalizedString("IDS_YES", tableName: "Main", comment: "")
        let titleNo = NSLocalizedString("IDS_NO", tableName: "Main", comment: "")
        if mGame.status != Game.Status.END {
            let message = NSLocalizedString("IDS_RESET", tableName: "Main", comment: "")
            let alertDialog = UIAlertController(title: " ", message: message, preferredStyle: .alert)
            alertDialog.addAction(UIAlertAction(title: titleNo, style: .cancel))
            alertDialog.addAction(UIAlertAction(title: titleYes, style: .default, handler: {
                // 用户单击了"是"，则设置游戏难度并重新开始
                action in
                self.mGame.difficulty = newDiff
            }))
            super.present(alertDialog, animated: true)
            return
        }
        
        // 设置难度
        mGame.difficulty = newDiff
        
        // 重新创建菜单
        mButtonShowMenu.menu = self.createMenu()
    }

    /**
     * "换图片"菜单项的单击响应方法。
     */
    @objc private func onMenuItemSetPictureClicked() {
        // 创建图片选择器
        let photoPicker = UIImagePickerController()
        photoPicker.delegate = self
        photoPicker.sourceType = .photoLibrary
        
        // 允许竖屏，因为图片选择器必须竖屏显示
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        appDelegate.allowPortrait = true

        // 显示图片选择器
        super.present(photoPicker, animated: true)
    }

    /**
     * "开始"菜单项的单击响应方法。
     */
    @objc private func onMenuItemStartClicked() {
        mGame.start()
    }

    /**
     * 隐藏状态栏。
     */
    internal override var prefersStatusBarHidden: Bool {
        return true
    }

    /**
     * 视图加载事件的响应方法。
     */
    internal override func viewDidLoad() {
        super.viewDidLoad()
        
        // 创建菜单
        mButtonShowMenu.showsMenuAsPrimaryAction = true
        mButtonShowMenu.menu = self.createMenu()

        // 设置开始按钮的尺寸和位置
        mButtonShowMenu.translatesAutoresizingMaskIntoConstraints = false
        let buttonSize = UIScreen.main.bounds.width * Const.SCALE_BUTTON_SIZE
        let lcButtonWidth = NSLayoutConstraint(item: mButtonShowMenu!, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: buttonSize)
        mButtonShowMenu.addConstraint(lcButtonWidth)

        let lcButtonHeight = NSLayoutConstraint(item: mButtonShowMenu!, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: buttonSize)
        mButtonShowMenu.addConstraint(lcButtonHeight)

        let lcButtonX = NSLayoutConstraint(item: mButtonShowMenu!, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1.0, constant: 0.0)
        view.addConstraint(lcButtonX)

        let lcButtonY = NSLayoutConstraint(item: mButtonShowMenu!, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: 0.0)
        view.addConstraint(lcButtonY)

        // 创建游戏区域
        let gameBoard = GameBoard(frame: UIScreen.main.bounds)
        view.addSubview(gameBoard)

        // 创建游戏
        mGame = Game(self, drawer: gameBoard.drawer, gameBoard: gameBoard)
        
        // 将"显示菜单"按钮置于最上面
        view.bringSubviewToFront(mButtonShowMenu)
        
        // 弹出提示
        let text = NSLocalizedString("IDS_TIP_TEXT", tableName: "Main", comment: "")
        Toast.makeText(view, text: text, duration: Toast.LENGTH_LONG).show()
    }
}
